package com.fxkj.cloud.drms.infra.sql.TDengine;

import com.fxkj.cloud.drms.infra.utils.AbstractBufferedRateExecutor;
import com.fxkj.cloud.drms.infra.utils.AsyncTaskContext;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import jakarta.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.sql.SQLException;

@Component
public class TDEngineBufferedRateWriteExecutor extends AbstractBufferedRateExecutor<TDEngineStatementTask<Boolean>, TDEngineResultSetFuture<Boolean>, TDEngineResultSet<Boolean>> {
    static final String BUFFER_NAME = "Write";

    public TDEngineBufferedRateWriteExecutor(
            @Value("${fx.ts.tdengine.query.buffer_size}") int queueLimit,
            @Value("${fx.ts.tdengine.query.concurrent_limit}") int concurrencyLimit,
            @Value("${fx.ts.tdengine.query.permit_max_wait_time}") long maxWaitTime,
            @Value("${fx.ts.tdengine.query.dispatcher_threads:2}") int dispatcherThreads,
            @Value("${fx.ts.tdengine.query.callback_threads:4}") int callbackThreads,
            @Value("${fx.ts.tdengine.query.poll_ms:50}") long pollMs) {
        super(queueLimit, concurrencyLimit, maxWaitTime, dispatcherThreads, callbackThreads, pollMs);
    }

    @PreDestroy
    public void stop() {
        super.stop();
    }

    @Override
    public String getBufferName() {
        return BUFFER_NAME;
    }

    @Override
    protected SettableFuture<TDEngineResultSet<Boolean>> create() {
        return SettableFuture.create();
    }

    @Override
    protected TDEngineResultSetFuture<Boolean> wrap(TDEngineStatementTask<Boolean> task, SettableFuture<TDEngineResultSet<Boolean>> future) {
        return new TDEngineResultSetFuture<Boolean>(future);
    }


    @Override
    protected ListenableFuture<TDEngineResultSet<Boolean>> execute(AsyncTaskContext<TDEngineStatementTask<Boolean>, TDEngineResultSet<Boolean>> taskCtx) {
        TDEngineStatementTask<Boolean> task = taskCtx.getTask();
        try {
            return task.executeAsync(Futures.immediateFuture(task.getPreStmt().execute()));
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
